import serial.tools.list_ports
from sinodev import SinoDeviceType, SinoDevice, SinoCommand


def comports(
    serial_baudrate: int = 115200,
    serial_timeout: float = 0.5,
    device_type: SinoDeviceType = SinoDeviceType.RTK,
    device_keywords: list[str] = ["USB"],
) -> list:
    def is_sinodev(serial_port):
        try:
            with SinoDevice(
                port=serial_port,
                baudrate=serial_baudrate,
                timeout=serial_timeout,
            ) as sndv:
                match device_type:
                    case SinoDeviceType.RTK | SinoDeviceType.SLAM:
                        sndv.write(SinoCommand.TO2)
                    case SinoDeviceType.RS | SinoDeviceType.MS:
                        sndv.write()
                return bool(sndv.read())
        except:
            return False

    ports = []
    for comport in serial.tools.list_ports.comports():
        desc = comport.description
        for keyword in device_keywords:
            if keyword in desc:
                break
        else:
            continue
        port = comport.device
        if is_sinodev(port):
            ports.append(port)

    ports.sort(key=lambda x: int(x[3:]))
    return ports
